Skip to content

Conversation

@Unique-Usman
Copy link
Contributor

No description provided.

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Jan 22, 2026
@rustbot
Copy link
Collaborator

rustbot commented Jan 22, 2026

r? @chenyukang

rustbot has assigned @chenyukang.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@Unique-Usman
Copy link
Contributor Author

My approach seems not to be perfect and I have been stucked on this for a while. This is the issue this is supposed to fix - >#117977

@Unique-Usman Unique-Usman marked this pull request as draft January 22, 2026 15:06
@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jan 22, 2026
@Unique-Usman
Copy link
Contributor Author

@estebank

@rust-log-analyzer

This comment has been minimized.

@rust-bors

This comment has been minimized.

Signed-off-by: Usman Akinyemi <usmanakinyemi202@gmail.com>
@Unique-Usman Unique-Usman marked this pull request as ready for review January 27, 2026 21:35
@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Jan 27, 2026
@Unique-Usman
Copy link
Contributor Author

r? @estebank

@rustbot rustbot assigned estebank and unassigned chenyukang Jan 27, 2026
@Unique-Usman
Copy link
Contributor Author

This is an improvement for

fn main() {
    let x = Some(42);
    if let Some(_) = x
        && Some(x) = x
    {}
}

initially it gives

error: expected expression, found `let` statement
 --> foo.rs:3:8
  |
3 |     if let Some(_) = x
  |        ^^^^^^^^^^^^^^^
  |
  = note: only supported directly in conditions of `if` and `while` expressions
help: you might have meant to continue the let-chain
  |
4 |         && let Some(x) = x
  |            +++
help: you might have meant to compare for equality
  |
4 |         && Some(x) == x
  |                     +

error[E0308]: mismatched types
 --> foo.rs:4:12
  |
4 |         && Some(x) = x
  |            ^^^^^^^ expected `bool`, found `Option<Option<{integer}>>`
  |
  = note: expected type `bool`
             found enum `Option<Option<{integer}>>`
help: use `Option::is_some` to test if the `Option` has a value
  |
4 |         && Some(x).is_some() = x
  |                   ++++++++++

error[E0308]: mismatched types
 --> foo.rs:3:8
  |
3 |       if let Some(_) = x
  |  ________^
4 | |         && Some(x) = x
  | |______________________^ expected `bool`, found `()`

error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0308`.

but now it gives

error: expected expression, found `let` statement
 --> foo.rs:3:8
  |
3 |     if let Some(_) = x
  |        ^^^^^^^^^^^^^^^
  |
  = note: -Ztrack-diagnostics: created at compiler/rustc_parse/src/parser/expr.rs:4263:51
  = note: only supported directly in conditions of `if` and `while` expressions
help: you might have meant to continue the let-chain
  |
4 |         && let Some(x) = x
  |            +++
help: you might have meant to compare for equality
  |
4 |         && Some(x) == x
  |                     +

error: aborting due to 1 previous error

@Unique-Usman
Copy link
Contributor Author

Interestingly,

fn main() {
    let x = Some(42);
    if let Some(_) = x
        && Some(x) = x
    {}
}

still give the same result.

error: expected expression, found `let` statement
 --> foo.rs:4:12
  |
4 |         && let Some(x) = x
  |            ^^^
  |
  = note: only supported directly in conditions of `if` and `while` expressions

error[E0308]: mismatched types
 --> foo.rs:3:18
  |
3 |     if Some(_) = x
  |                  ^ expected `bool`, found `Option<{integer}>`
  |
  = note: expected type `bool`
             found enum `Option<{integer}>`

error[E0308]: mismatched types
 --> foo.rs:3:8
  |
3 |       if Some(_) = x
  |  ________^^^^^^^___-
  | |        |
  | |        expected `bool`, found `Option<_>`
4 | |         && let Some(x) = x
  | |__________________________- this expression has type `bool`
  |
  = note: expected type `bool`
             found enum `Option<_>`

error[E0308]: mismatched types
 --> foo.rs:3:8
  |
3 |       if Some(_) = x
  |  ________^
4 | |         && let Some(x) = x
  | |__________________________^ expected `bool`, found `()`
  |
help: consider adding `let`
  |
3 |     if let Some(_) = x
  |        +++

error: aborting due to 4 previous errors

For more information about this error, try `rustc --explain E0308`.

Copy link
Contributor

@estebank estebank left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure I follow your last comment. The diagnostic you're showing doesn't correspond with the code. I think you meant the following?

fn main() {
    let x = Some(42);
    if Some(_) = x
        && let Some(x) = x
    {}
}

If so, this is the output I see:

error: expected expression, found `let` statement
 --> foo.rs:4:12
  |
4 |         && let Some(x) = x
  |            ^^^
  |
  = note: -Ztrack-diagnostics: created at /rustc-dev/4fa80a5e733e2202d7ca4c203c2fdfda41cfe7dc/compiler/rustc_parse/src/parser/expr.rs:2775:43
  = note: only supported directly in conditions of `if` and `while` expressions

error[E0308]: mismatched types
 --> foo.rs:3:18
  |
3 |     if Some(_) = x
  |                  ^ expected `bool`, found `Option<{integer}>`
  |
  = note: -Ztrack-diagnostics: created at /rustc-dev/4fa80a5e733e2202d7ca4c203c2fdfda41cfe7dc/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs:1905:35
  = note: expected type `bool`
             found enum `Option<{integer}>`

error[E0308]: mismatched types
 --> foo.rs:3:8
  |
3 |       if Some(_) = x
  |  ________^^^^^^^___-
  | |        |
  | |        expected `bool`, found `Option<_>`
4 | |         && let Some(x) = x
  | |__________________________- this expression has type `bool`
  |
  = note: -Ztrack-diagnostics: created at /rustc-dev/4fa80a5e733e2202d7ca4c203c2fdfda41cfe7dc/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs:1905:35
  = note: expected type `bool`
             found enum `Option<_>`

error[E0308]: mismatched types
 --> foo.rs:3:8
  |
3 |       if Some(_) = x
  |  ________^
4 | |         && let Some(x) = x
  | |__________________________^ expected `bool`, found `()`
  |
  = note: -Ztrack-diagnostics: created at /rustc-dev/4fa80a5e733e2202d7ca4c203c2fdfda41cfe7dc/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs:1905:35
help: consider adding `let`
  |
3 |     if let Some(_) = x
  |        +++

And I think it's coming from a different part of the parser, in parse_expr_let, so it would require different specific handling.

View changes since this review

Comment on lines 26 to 30
help: a function with a similar name exists
|
LL - if (i + j) = i {}
LL + if (a + j) = i {}
|
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unrelated: Noticing this suggestion and it is quite bad :-/

Comment on lines -25 to -37
error: binary assignment operation `+=` cannot be used in a let chain
--> $DIR/let-chains-assign-add-incorrect.rs:8:31
|
LL | if let _ = 1 && true && y += 2 {};
| ---------------------- ^^ cannot use `+=` in a let chain
| |
| you are add-assigning the right-hand side expression to the result of this let-chain
|
help: you might have meant to compare with `==` instead of assigning with `+=`
|
LL - if let _ = 1 && true && y += 2 {};
LL + if let _ = 1 && true && y == 2 {};
|
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change makes me think that we might want to restrict the silencing to cases where we had any suggestions. The need to remove the run-rustfix generally points at us giving less ideal output. That being said, this code as is is not great to begin with, and == would likely be intended... Can you see if we can make it so that we don't cause changes on this output while still silencing the others?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, that is valid. Looks quite weird to me also, I knew we had to do some restrictions, I will do that.

missing_let: self.missing_let,
comparison: self.comparison,
});
self.found_incorrect_let_chain = Some(guar);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think all you'd have to do is gate this behind missing_let or comparison being Some.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, thanks. I did gate it earlier, but not around Some parts, so it didn’t work. I’ll gate it around it now.

@Unique-Usman
Copy link
Contributor Author

I'm not sure I follow your last comment. The diagnostic you're showing doesn't correspond with the code. I think you meant the following?

fn main() {
    let x = Some(42);
    if Some(_) = x
        && let Some(x) = x
    {}
}

If so, this is the output I see:

error: expected expression, found `let` statement
 --> foo.rs:4:12
  |
4 |         && let Some(x) = x
  |            ^^^
  |
  = note: -Ztrack-diagnostics: created at /rustc-dev/4fa80a5e733e2202d7ca4c203c2fdfda41cfe7dc/compiler/rustc_parse/src/parser/expr.rs:2775:43
  = note: only supported directly in conditions of `if` and `while` expressions

error[E0308]: mismatched types
 --> foo.rs:3:18
  |
3 |     if Some(_) = x
  |                  ^ expected `bool`, found `Option<{integer}>`
  |
  = note: -Ztrack-diagnostics: created at /rustc-dev/4fa80a5e733e2202d7ca4c203c2fdfda41cfe7dc/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs:1905:35
  = note: expected type `bool`
             found enum `Option<{integer}>`

error[E0308]: mismatched types
 --> foo.rs:3:8
  |
3 |       if Some(_) = x
  |  ________^^^^^^^___-
  | |        |
  | |        expected `bool`, found `Option<_>`
4 | |         && let Some(x) = x
  | |__________________________- this expression has type `bool`
  |
  = note: -Ztrack-diagnostics: created at /rustc-dev/4fa80a5e733e2202d7ca4c203c2fdfda41cfe7dc/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs:1905:35
  = note: expected type `bool`
             found enum `Option<_>`

error[E0308]: mismatched types
 --> foo.rs:3:8
  |
3 |       if Some(_) = x
  |  ________^
4 | |         && let Some(x) = x
  | |__________________________^ expected `bool`, found `()`
  |
  = note: -Ztrack-diagnostics: created at /rustc-dev/4fa80a5e733e2202d7ca4c203c2fdfda41cfe7dc/compiler/rustc_trait_selection/src/error_reYeahporting/infer/mod.rs:1905:35
help: consider adding `let`
  |
3 |     if let Some(_) = x
  |        +++

And I think it's coming from a different part of the parser, in parse_expr_let, so it would require different specific handling.

View changes since this review

Yeah, I meant this. Yeah, it needs to be handle in different part of the code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants